home *** CD-ROM | disk | FTP | other *** search
/ CD ROM Paradise Collection 4 / CD ROM Paradise Collection 4 1995 Nov.iso / program / swaga_c.zip / COMM.SWG / 0058_Mail Manager.pas < prev    next >
Pascal/Delphi Source File  |  1994-08-25  |  17KB  |  581 lines

  1. {
  2. From: ac_march@ECE.Concordia.CA (Angus C. March)
  3.  
  4. I have this grave problem where when I use this certain program that calls a
  5. function that I defined in a unit, the program shortly hangs up. Oddly enough
  6. if I start peppering the regions of code about where the hang up occurs it is
  7. delayed. As another interesting piece of information: pushing ctrl-break
  8. causes the hangup as well.
  9.      Anyway, the following is a Turbo Pascal 6.0 partially written in
  10. Borland.  It's REAL LONG, so I'm not going to expect anyone to sift through
  11. all the code, that is why I have COMMENTED THE KEY POINTS IN CODE w/UPPERCASE
  12. LETTERS, so it will be MUCH EASER TO FIND. Just like a comic book advert for
  13. a martial arts course.
  14.  
  15.      Anyway, here is all the code.
  16. }
  17.  
  18. Program mailManager;
  19.  
  20. Uses DOS, CRT, AngusU; {AngusU= A UNIT WITH MY OWN ROUTINES, SEE END IF
  21.                                 POST}
  22.  
  23. Const
  24.      background = Blue;
  25.      foreground = LightGray;
  26.  
  27.      scrX = 80;
  28.      scrY = 25;
  29.      scrXY = 80*25;
  30.  
  31.  
  32. Type          {screen save types}
  33.     scrXRange = 1..scrX;  {x-axis range of my screen}
  34.     scrYRange = 1..scrY;  {y-  "    "   "  "    "}
  35.     scrXYRange = 1..scrXY;
  36.     scrElementRecord = Record  {attributes of a cell on the text screen}
  37.                        element: Char;
  38.                        colour: Byte;
  39.     end;
  40.     scrPointer = ^scrNode;
  41.     scrNode = Record          {linked list of window to be put on the stack}
  42.               cell: scrElementRecord;
  43.               next: scrPointer;
  44.     end;
  45.     scrStackPointer = ^stackNode;       {These set the stack}
  46.     stackNode = Record
  47.                 scrWindowPointer: scrPointer; {pointer to window to be saved}
  48.                 cursorX, {where cursor was left}
  49.                 left, right: scrXRange; {boundries of the window to be saved}
  50.                 cursorY, {where cursor was left}
  51.                 top, bottom: scrYRange; {boundries of the window to be save}
  52.                 winMax, winMin: Word; {boundries of the window}
  53.                 colour: Byte;  {textAttr}
  54.                 downward: scrStackPointer; {pointer to next place in stack}
  55.     end;
  56.  
  57.                       {menuTypes}
  58.     stringPointer = ^stringNode;
  59.     stringNode = Record
  60.          prev,next: stringPointer;  {strings passed to menu}
  61.          streng: String;
  62.     end;
  63.  
  64.  
  65. Var
  66.    dummy, menuAnswer: Char;
  67.    p: DirPointer;
  68.    head, bufferPointer, q: stringPointer;
  69.    menuCand: String;
  70.    COUNTER: Byte;
  71.    EXTENDED: BOOLEAN;
  72.  
  73.    {screen save vars}
  74.    scrStack: scrStackPointer;
  75.  
  76.  
  77. {Procedure colorWindow;
  78. Var
  79.    i: Word;
  80.  
  81. Begin
  82.      TextBackground(White);
  83.      For i:= 1 To 2000 Do
  84.          Write(' ');
  85. end;}
  86.  
  87.  
  88. Function strg(x: Longint): String;
  89. Var
  90.    carry: String;
  91.  
  92. Begin
  93.      Str(x, carry);
  94.      strg:= carry;
  95. end;
  96.  
  97.  
  98. Procedure message(messg: String);
  99. Var
  100.    carryWindMax, carryWindMin: Word;
  101.    carryWhereX: scrXRange;
  102.    carryWhereY: scrYRange;
  103.  
  104. Begin
  105.      carryWhereX:= WhereX; carryWhereY:= WhereY;
  106.      carryWindMax:= WindMax; carryWindMin:= WindMin;
  107.      Window(1, 25, 80, 25);
  108.      Write(messg);
  109.      WindMax:= carryWindMax; WindMin:= carryWindMin;
  110.      GotoXY(carryWhereX, carryWhereY);
  111. end;
  112.  
  113.  
  114. Procedure shiftWindow(xShift, yShift: Shortint);
  115. Begin
  116.      Window(Lo(WindMin) + 1 + xShift, Hi(WindMin) + 1 + yShift, Lo(WindMax) +
  117. 1 + xShift, Hi(WindMax) + 1 + yShift);
  118. end;
  119.  
  120.  
  121. Procedure getCursorChar(Var attrib, charCode: Byte);
  122. {THIS THING DOESN'T WORK VERY WELL BUT IT ISN'T CAUSING THE PROBLEM
  123. BECAUSE THE PROBLEM REMAINS WHEN THIS PROCEDURE IS REMOVED FROM THE CODE}
  124. Var
  125.    reg: Registers;{regPack}
  126.  
  127. Begin
  128.      Reg.AH := 8;  {Function 8 = Read attribute and character at cursor.}
  129.      Reg.BH := 0;  {Use display page = 0}
  130.  
  131.      Intr(10,Reg); {Call Interrupt 10 (BIOS)}
  132.  
  133.      attrib := Reg.AH;  {Get atrribute value from result.}
  134.      charCode:= Reg.AL; {Get character code from result.}
  135. end;
  136.  
  137.  
  138. Procedure getChar(x: scrXRange; y: scrYRange; Var cell: scrElementRecord);
  139. Var
  140.    xCarry: scrXRange;
  141.    yCarry: scrYRange;
  142.    colour, charOrd: Byte;
  143.  
  144. Begin
  145.      xCarry:= WhereX; yCarry:= WhereY;
  146.      GotoXY(x, y);
  147.      getCursorChar(colour, charOrd);
  148.      cell.colour:= colour;
  149.      cell.element:= Chr(charOrd);
  150. dummy:= WriteRead('');  {THIS IS INSTRUMENTAL IN THE PROBLEM! IF I TAKE THIS
  151. OUT THE PROBLEM GOES AWAY... FOR A WHILE. SEE THE END OF THE PROGRAM FOR
  152. THE IMPLEMENTATION OF THE ANGUSU UNIT}
  153.      GotoXY(xCarry, yCarry);
  154. end;
  155.  
  156.  
  157. Function oneString(counter: Byte): String;
  158. Var
  159.    i: Byte;
  160.    beg, j: Word;
  161.    theString, letters: String;
  162.  
  163. Begin
  164.      j:= 1;
  165.      letters:= '';
  166.      theString:= 'Hi I''m Wayne Gretzky I scored 92 goals 10 years ago and
  167. anyone who sez n that I''m a homosexual can go';
  168. {     theString:= ConCat(theString, ' get run over by a starship. Max, you sly
  169. puss. Good grief this could take for Moncton');}
  170. {     theString:= ConCat(theString, ' ever I mean all the things that we have
  171. to write');}
  172.      For i:= 1 To counter Do
  173.      Begin
  174.           beg:= j;
  175.           While Not(thestring[j] = ' ') And (j < Length(theString)) Do
  176.                 j:= j + 1;
  177.           j:= j + 1;
  178.      end;
  179.      If j > Length(theString) Then
  180.         letters:= ''
  181.      Else
  182.          For i:= beg To j - 1 Do
  183.              letters:= Concat(letters,theString[i]);
  184.      oneString:= letters;
  185. end;
  186.  
  187.  
  188. {Procedure scrSaveParam;}
  189.  
  190.  
  191. Procedure initStack;
  192. Begin
  193.      scrStack:= Nil;
  194. end;
  195.  
  196.  
  197. Procedure scrPush(scr: scrPointer; left, right: scrXRange;
  198.                          top, bottom: scrYRange);
  199. Var
  200.    carryStackPointer: scrStackPointer;
  201.    carryWindMax, carryWindMin: Word;
  202.  
  203. Begin
  204.      carryWindMax:= WindMax; carryWindMin:= WindMin;
  205.  
  206.      Window(1, 1, 80, 25);
  207.      carryStackPointer:= scrStack;
  208.      New(scrStack);
  209.      scrStack^.cursorX:= WhereX; scrStack^.cursorY:= WhereY;
  210.      scrStack^.winMax:= carryWindMax; scrStack^.winMin:= carryWindMin;
  211.      scrStack^.colour:= TextAttr;
  212.      scrStack^.scrWindowPointer:= scr;
  213.      scrStack^.left:= left; scrStack^.right:= right; scrStack^.top:= top;
  214. scrStack^.bottom:= bottom;
  215.      scrStack^.downward:= carryStackPointer;
  216.      WindMax:= carryWindMax; WindMin:= carryWindMin;
  217. end;
  218.  
  219.  
  220. Procedure scrPop(Var scr: scrPointer; Var left, right: scrXRange;
  221.                         Var top, bottom: scrYRange);
  222. Var
  223.    carry: scrStackPointer;
  224.  
  225. Begin
  226.      Window(1, 1, 80, 25);
  227.      GotoXY(scrStack^.cursorX, scrStack^.cursorY);
  228.      WindMax:= scrStack^.winMax; WindMin:= scrStack^.winMin;
  229.      TextAttr:= scrStack^.colour;
  230.      scr:= scrStack^.scrWindowPointer;
  231.      left:= scrStack^.left; right:= scrStack^.right; top:= scrStack^.top;
  232. bottom:= scrStack^.bottom;
  233.      carry:= scrStack;
  234.      scrStack:= scrStack^.downward;
  235.      Dispose(carry);
  236. end;
  237.  
  238.  
  239. Procedure initWindowPointer(Var pointer: scrPointer);
  240. Begin
  241.      pointer:= Nil;
  242. end;
  243.  
  244.  
  245. Procedure scrStoreElement(Var pointer: scrPointer; Var cell: scrElementRecord);
  246. Var
  247.    buffer: scrPointer;
  248.    messg: Char;
  249.  
  250. Begin
  251.      New(buffer);
  252.      buffer^.cell:= cell;
  253. {messg:= buffer^.cell.element;
  254. message(messg);
  255. Write('We are now saving ',Ord(messg));}
  256.      buffer^.next:= Nil;
  257.      If pointer = Nil Then
  258.         pointer:= buffer
  259.      Else
  260.          pointer^.next:= buffer;
  261. end;
  262.  
  263. Procedure scrRetrieveElement(Var pointer: scrPointer; Var charChar: Char);
  264. Var
  265.    carry: scrPointer;
  266.  
  267. Begin
  268.      If pointer= Nil Then
  269.         WriteLn('hey this is Nil!')
  270.      Else
  271.      Begin
  272.      charChar:= pointer^.cell.element;
  273.      TextAttr:= pointer^.cell.colour;
  274.      carry:= pointer;
  275.      pointer:= pointer^.next;
  276.      Dispose(carry);
  277.      end;
  278. end;
  279.  
  280.  
  281. Procedure windowSave;
  282. Var
  283.    x: scrXRange;
  284.    y: scrYRange;
  285.    windowPointer: scrPointer;
  286.    cell: scrElementRecord;
  287.  
  288. Begin
  289.      initWindowPointer(windowPointer);
  290.      For y:= Hi(WindMin) + 1 To Hi(WindMax) + 1 Do
  291.          For x:= Lo(WindMin) + 1 To Lo(WindMax) + 1 Do
  292.          Begin
  293.               getChar(x, y, cell);
  294.               WriteLn('Ok, I get here',x,' ',y,' ',cell.colour,'
  295. ',Ord(cell.element));
  296.               scrStoreElement(windowPointer, cell);
  297.          end;
  298.      scrPush(windowPointer, Lo(WindMin) + 1, Lo(WindMax) + 1, Hi(WindMin) + 1,
  299. Hi(WindMax) + 1);
  300. end;
  301.  
  302.  
  303. Procedure windowRetrieve;
  304. Var
  305.    x, left, right: scrXRange;
  306.    y, top, bottom: scrYRange;
  307.    windowPointer: scrPointer;
  308.    element: Char;
  309.  
  310. Begin
  311.      scrPop(windowPointer, left, right, top, bottom);
  312.      scrPush(windowPointer, 1, 1, 1, 1);
  313.      Window(1, 1, 80, 25);
  314.      For y:= top To bottom Do
  315.          For x:= left To right Do
  316.          Begin
  317.               GotoXY(x, y);
  318. If Not(windowPointer = Nil) Then
  319.               scrRetrieveElement(windowPointer, element);
  320.               Write(element);
  321.          end;
  322.      scrPop(windowPointer, left, right, top, bottom);
  323. end;
  324.  
  325.  
  326. Procedure drawMenu(head: stringPointer; Var extended: Boolean);
  327. {THIS PROCEDURE IS PASSED A SET OF STRINGS, LINKED-LISTED, AND MAKE A MENU
  328. OF THEM}
  329. Var
  330.    size, longest: Word;
  331.  
  332.    bufferPointer: stringPointer;
  333.    menuWidth, x, middleX: scrXRange;
  334.    menuHeight, y,middleY: scrYRange;
  335.  
  336. Begin
  337.  
  338.      bufferPointer:= head;
  339.      size:= 0; longest:= 0;
  340.  
  341.      While Not(bufferPointer = Nil) Do
  342.      Begin
  343.           size:= size + 1;
  344.           If (Length(bufferPointer^.streng) > longest) Then longest:=
  345. Length(bufferPointer^.streng);
  346.           bufferPointer:= bufferPointer^.next;
  347.      end;
  348.      extended:= ((size + 1) Div 2) > (Hi(WindMax) - Hi(WindMin) - 3);
  349.  
  350.      middleX:= (Lo(WindMax) - Lo(WindMin) + 1) Div 2;
  351.      middleY:= (Hi(WindMax) - Hi(WindMin) + 1) Div 2;
  352.      If extended Then
  353.         Window(middleX - (longest + 1), Hi(WindMin) + 1, middleX + longest + 2,
  354.                        Hi(WindMax) + 1)
  355.      Else
  356.          Window(middleX - (longest + 1), (middleY - 1) - (size - 1) Div 4,
  357.                         middleX + longest + 2, (middleY + 1) + (size + 1) Div
  358. 4);
  359.      shiftWindow(-25, -4);
  360.      windowSave;
  361.      menuWidth:= Lo(WindMax) - Lo(WindMin) - 1;
  362.      menuHeight:= Hi(WindMax) - Hi(WindMin) + 1;
  363.      If extended Then menuHeight:= menuHeight - 1;
  364.      middleX:= (Lo(WindMax) - Lo(WindMin)) Div 2;
  365.      middleY:= (Hi(WindMax) - Hi(WindMin) + 1) Div 2;
  366.      GotoXY(1, 1);
  367.      TextColor(White); Write('╔'); For x:= 1 To menuWidth - 2 Do Write('═');
  368. WriteLn('╗');
  369.      For y:= 2 To menuHeight - 1 Do
  370.      Begin
  371.           TextColor(White); Write('║'); TextColor(Yellow);
  372.           Write(head^.streng);
  373.           clrEol;
  374.           If Not(head^.next = Nil) Then
  375.           Begin
  376.                GotoXY(middleX + 2, y);
  377.                Write(head^.next^.streng);
  378.           end;
  379.           head:= head^.next^.next;
  380.           GotoXY(menuWidth, y);
  381.           TextColor(White); WriteLn('║'); TextColor(Yellow);
  382.      end;
  383.      TextColor(White);
  384.      If extended Then
  385.      Begin
  386.           Write('║');
  387.           GotoXY(middleX - 8, WhereY);
  388.           Write('Page Up/Page Down');
  389.           GotoXY(menuWidth, WhereY);
  390.           WriteLn('║');
  391.  
  392.      end;
  393.      Write('╚'); For x:= 1 To menuWidth - 2 Do Write('═'); Write('╝');
  394. end;
  395.  
  396.  
  397. Procedure writeLnHighLight(streng: String; foreground, background: Byte);
  398. Var
  399.    i: Shortint;
  400.    textStart: Byte;
  401.  
  402. Begin
  403.      textStart:= TextAttr;
  404.      TextBackground(background);
  405.      TextColor(foreground);
  406.      For i:= 1 To Length(streng) Do
  407.      Begin
  408.           If streng[i] = '(' Then
  409.              TextColor(White)
  410.           Else
  411.               If streng[i] = ')' Then
  412.                  TextColor(foreground)
  413.               Else
  414.                   Write(streng[i]);
  415.      end;
  416.      WriteLn;
  417.      TextAttr:= textStart;
  418. end;
  419.  
  420.  
  421. Begin
  422.      COUNTER:= 1;
  423.      menuAnswer:= ' ';
  424.      TextBackground(background);
  425.      TextColor(foreground);
  426.      ClrScr;
  427.  
  428.      writeLnHighLight(' Mailing (L)ist             (C)onfigure Schedual       
  429.       (M)ail             E(x)it',
  430.                                LightBlue, LightGray);
  431.      Window(1, 2, 80, 25);
  432.  
  433.      menuCand:= 'Wayne Gretzky';
  434.      WriteLn('Ok tell Santa what you want to put in the menu');
  435.      New(bufferPointer);
  436.      head:= bufferPointer;
  437.      q:= Nil;
  438.      While Not(menuCand = '') Do
  439.      Begin
  440.           menuCand:= oneString(COUNTER);
  441.           COUNTER:= COUNTER + 1;
  442.           If Not(menuCand = '') Then
  443.           Begin
  444.                q^.next:= bufferPointer; bufferPointer^.prev:= q;
  445. bufferPointer^.next:= Nil;
  446.                bufferPointer^.streng:= menuCand;
  447.                q:= bufferPointer;
  448.                New(bufferPointer);
  449.           end;
  450.      end;
  451. {THIS PART OF THE PROGRAM IS JUST TRYING TO DRAW A MENU AND SEE IF IT CAN BE
  452. READ OFF THE SCREEN. SO FAR I HAVEN'T HAD MUCH LUCK.}
  453.      drawMenu(head, extended);
  454.      dummy:= WriteRead('Just lemme know when you''re tired of looking at it
  455. (Anykey)');
  456.      windowRetrieve;
  457.      While Not(menuAnswer = 'X') Do
  458.      Begin
  459.           menuAnswer:= WriteRead('');
  460.      end;
  461. end.
  462.  
  463.  
  464.  
  465. Unit AngusU;
  466.  
  467. Interface
  468.          Uses DOS, CRT;
  469.  
  470.          Type
  471.              RealDecimalRange = 0..38;
  472.  
  473.              DirPointer = ^listpointer;
  474.              listpointer = Record
  475.                          results: SearchRec;
  476.                          next: DirPointer;
  477.              end;
  478.  
  479.          Function WriteRead(message: String): Char;
  480.          {Outputs messages, and waits for a single key input}
  481.  
  482.          Function WriteReadLn(message: String): String;
  483.          {Outputs message, and waits for entered keyboard input}
  484.  
  485.          Procedure Dir(pathway: PathStr; Var list: DirPointer);
  486.          {Do the Gilligan's directory thing, and return attributes in linked
  487. list}
  488.  
  489.          Function AllUpCase(streng: String): String;
  490.  
  491.          Function Log(argu: Real): Real;
  492.          {Returns common logrithm}
  493.  
  494.          Function DeScience(input: Real; decimal: RealDecimalRange): String;
  495.          {Reads a real number and outputs it in string}
  496.  
  497.  
  498. Implementation
  499.               Function WriteRead(message: string): Char;
  500. {SO FAR, OTHER THAN ONE OF THE TYPES THIS IS THE ONLY THING FROM THIS UNIT
  501. THAT I INVOKE. AGAIN, IF I REMOVE THE CODE FROM MY CALLER PROGRAM (I FORGET THE
  502. PROGRAMMER JARGON FOR IT) THE PROBLEM SEEM TO DECREASE}.
  503.               {Outputs messages, and waits for a single key input}
  504.               Begin
  505.                    Write(message);
  506.                    WriteRead:= UpCase(ReadKey);
  507.               end;
  508.  
  509.  
  510.               Function WriteReadLn(message: String): String;
  511.               {Outputs message, and waits for entered keyboard input}
  512.               Var
  513.                  buffer: String;
  514.  
  515.               Begin
  516.                    Write(message);
  517.                    ReadLn(buffer);
  518.                    WriteReadLn:= buffer;
  519.               end;
  520.  
  521.  
  522.               Procedure Dir(pathway: PathStr; Var list: DirPointer);
  523.               {Do the Gilligan's directory thing, and return attributes in
  524. linked list}
  525.               Var
  526.                  carry, buffer: DirPointer;
  527.                  searchBuff: SearchRec;
  528.                  i, j: Integer;
  529.  
  530.               Begin
  531.                    New(list);
  532.                    FindFirst(pathway, AnyFile, searchBuff);
  533.                    If DosError = 0 Then
  534.                       list^.results:= searchBuff;
  535.  
  536.                    New(buffer);
  537.                    list^.next:= buffer;
  538.                    carry:= list;
  539.                    While DosError = 0 Do
  540.                    Begin
  541.                         FindNext(searchBuff);
  542.                         buffer^.results:= searchBuff;
  543.                         If DosError = 0 Then
  544.                         Begin
  545.                              carry:= buffer;
  546.                              New(buffer);
  547.                              carry^.next:= buffer;
  548.                         end;
  549.                    end;
  550.                    carry^.next:= Nil;
  551.               end;
  552.  
  553.  
  554.               Function AllUpCase(streng: String): String;
  555.               Var
  556.                  i: Integer;
  557.  
  558.               Begin
  559.                    For i:= 1 To Length(streng) Do
  560.                    streng[i]:= UpCase(streng[i]);
  561.                    AllUpCase:= streng
  562.               end;
  563.  
  564.  
  565.               Function Log(argu: Real): Real;
  566.               Begin
  567.                    Log:= Ln(argu)/Ln(10);
  568.               end;
  569.  
  570.  
  571.               Function DeScience(input: Real; decimal: realDecimalRange):
  572. String;
  573.               {Reads a real number and outputs it in string}
  574.               Var
  575.                  buffer: String;
  576.               Begin
  577.                    Str(input: trunc(Log(input) + 1): decimal, buffer);
  578.                    DeScience:= buffer;
  579.               end;
  580. end.
  581.